package com.zmn.oms.common.utils;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.FileEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.File;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * http/https请求工具类
 * 
 */

@SuppressWarnings("deprecation")
public class HttpUtil {
	private static Logger logger = LoggerFactory.getLogger(HttpUtil.class);
	private static final String USER_AGENT = "Mozilla/5.0 (Windows; U; Windows NT 6.0; zh-CN; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8 (.NET CLR 3.5.30729)";

	public static HttpClient getHttpClient() {
		// Create and initialize HTTP parameters
		HttpParams params = new BasicHttpParams();
		ConnManagerParams.setMaxTotalConnections(params, 100);
		// ConnManagerParams.setTimeout(params, 60*1000);
		HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
		params.setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, false);
		params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 10 * 1000);
		params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 60 * 1000);

		params.setLongParameter(ClientPNames.CONN_MANAGER_TIMEOUT, 200L);// //该值就是连接不够用的时候等待超时时间，一定要设置，而且不能太大

		PoolingClientConnectionManager conMgr = new PoolingClientConnectionManager();
		conMgr.setMaxTotal(200); // 设置整个连接池最大连接数 根据自己的场景决定
		// 是路由的默认最大连接（该值默认为2），限制数量实际使用DefaultMaxPerRoute并非MaxTotal。
		// 设置过小无法支持大并发(ConnectionPoolTimeoutException: Timeout waiting for
		// connection from pool)，路由是对maxTotal的细分。
		conMgr.setDefaultMaxPerRoute(conMgr.getMaxTotal());// （目前只有一个路由，因此让他等于最大值）

		// Create and initialize scheme registry
		SchemeRegistry schemeRegistry = new SchemeRegistry();
		schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));

		// Create an HttpClient with the ThreadSafeClientConnManager.
		// This connection manager must be used if more than one thread will
		// be using the HttpClient.
		ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
		HttpClient httpClient = new DefaultHttpClient(cm, params);
		// httpClient.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS,
		// false);

		return httpClient;
	}

	public static HttpClient getHttpsClient() throws NoSuchAlgorithmException, KeyManagementException {

		// 证书管理器
		X509TrustManager tm = new X509TrustManager() {
			public java.security.cert.X509Certificate[] getAcceptedIssuers() {
				return null;
			}

			@Override
			public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {
			}

			@Override
			public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {
			}
		};

		SSLContext ctx = SSLContext.getInstance("TLS");
		ctx.init(null, new TrustManager[] { tm }, null);
		SSLSocketFactory ssf = new SSLSocketFactory(ctx);
		ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
		
		HttpClient httpclient = new DefaultHttpClient();

		// 注册
		ClientConnectionManager ccm = httpclient.getConnectionManager();
		SchemeRegistry sr = ccm.getSchemeRegistry();
		sr.register(new Scheme("https", 443, ssf));
		
		// 参数设置
		HttpParams params = httpclient.getParams();
		params.setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, false);
		params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 10 * 1000);
		params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 60 * 1000);
		params.setLongParameter(ClientPNames.CONN_MANAGER_TIMEOUT, 100L);// //该值就是连接不够用的时候等待超时时间，一定要设置，而且不能太大

		ConnManagerParams.setMaxTotalConnections(params, 100);
		HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);

		return httpclient;

	}

	private static String getResponse(HttpEntity httpEntity, String encode) throws Exception {
		return EntityUtils.toString(httpEntity, encode);
	}

	/**
	 * http get 请求（字符编码为utf-8）
	 * 
	 * @param url
	 *            http请求地址
	 * @return
	 */
	public static String httpGet(String url) throws Exception {
		return httpGet(url, "utf-8");
	}

	/**
	 * http get 请求
	 * 
	 * @param url
	 *            http请求地址
	 * @param encode
	 *            字符编码
	 * @return
	 */
	public static String httpGet(String url, String encode) throws Exception {
		return get(getHttpClient(), url, encode);
	}

	/**
	 * https get 请求（字符编码为utf-8）
	 * 
	 * @param url
	 *            http请求地址
	 * @return
	 */
	public static String httpsGet(String url) throws Exception {
		return httpsGet(url, "utf-8");
	}

	/**
	 * https get 请求
	 * 
	 * @param url
	 *            http请求地址
	 * @param encode
	 *            字符编码
	 * @return
	 */
	public static String httpsGet(String url, String encode) throws Exception {
		return get(getHttpsClient(), url, encode);
	}

	/**
	 * http post 请求（字符编码为utf-8）
	 * 
	 * @param url
	 *            http请求地址
	 * @return
	 */
	public static String httpPost(String url) throws Exception {
		return httpPost(url, "");
	}

	/**
	 * http post 请求（字符编码为utf-8）
	 * 
	 * @param url
	 *            http请求地址
	 * @param content
	 *            post 的内容
	 * @return
	 */
	public static String httpPost(String url, String content) throws Exception {
		return httpPost(url, content, "utf-8");
	}

	/**
	 * http post 请求（字符编码为utf-8）
	 * 	 * @param url http请求地址
	 * 	 * @param content post 的内容
	 * 	 * @param encode 字符编码
	 * @return
	 */
	public static String httpPost(String url, String content, String encode) throws Exception {
		return post(getHttpClient(), url, content, null, encode);
	}

	/**
	 * http post 请求（字符编码为utf-8）
	 * @param url http请求地址
	 * @param content post 的内容
	 * @param headers 请求头信息
	 * @return
	 */
	public static String httpPost(String url, String content, Map<String, String> headers) throws Exception {
		return post(getHttpClient(), url, content, headers, "utf-8");
	}

	public static String httpPost(String url, Map<String, String> params) throws Exception {
		return httpPost(url, params, "utf-8");
	}

	/**
	 * https post 请求（字符编码为utf-8）
	 * 
	 * @param url
	 *            https请求地址
	 * @return
	 */
	public static String httpsPost(String url) throws Exception {
		return httpsPost(url, "");
	}

	/**
	 * https post 请求（字符编码为utf-8）
	 * 
	 * @param url
	 *            https请求地址
	 * @param content
	 *            post 的内容
	 * @return
	 */
	public static String httpsPost(String url, String content) throws Exception {
		return httpsPost(url, content, "utf-8");
	}
	

	/**
	 * https post 请求
	 * 
	 * @param url
	 *            https请求地址
	 * @param content
	 *            post 的内容
	 * @param encode
	 *            字符编码
	 * @return
	 */
	public static String httpsPost(String url, String content, String encode) throws Exception {
		return post(getHttpsClient(), url, content, null, encode);
	}
	
	public static String httpsPost(String url, Map<String, String> params) throws Exception {
		return post(getHttpsClient(), url, params, "utf-8");
	}

	public static String httpPost(String url, Map<String, String> params, String encode) throws Exception {
		return post(getHttpClient(), url, params, encode);
	}

	public static String httpsPost(String url, String content, Map<String, String> params) throws Exception {
		return post(getHttpsClient(), url, content,params);
	}

	public static String doGet(String url, Map<String, String> header) throws Exception{
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		String result = "";
		try {
			// 通过址默认配置创建一个httpClient实例
			httpClient = HttpClients.createDefault();
			// 创建httpGet远程连接实例
			HttpGet httpGet = new HttpGet(url);
			// 设置请求头信息，鉴权
			for (String key : header.keySet()) {
				httpGet.setHeader(key, header.get(key));
			}
			// 设置配置请求参数
			RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 连接主机服务超时时间
					.setConnectionRequestTimeout(35000)// 请求超时时间
					.setSocketTimeout(60000)// 数据读取超时时间
					.build();
			// 为httpGet实例设置配置
			httpGet.setConfig(requestConfig);
			// 执行get请求得到返回对象
			response = httpClient.execute(httpGet);
			// 通过返回对象获取返回数据
			HttpEntity entity = response.getEntity();
			// 通过EntityUtils中的toString方法将结果转换为字符串
			result = EntityUtils.toString(entity);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			// 关闭资源
			if (null != response) {
				EntityUtils.consume(response.getEntity()); // 会自动释放连接
			}
			if (null != httpClient) {
				try {
					httpClient.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return result;
	}

	public static String get(HttpClient httpClient, String url, String encode) throws Exception {
		HttpResponse response = null;
		String ret = "";
		try {
			HttpGet httpget = new HttpGet(url);
			httpget.addHeader("User-Agent", USER_AGENT);
			response = httpClient.execute(httpget);
			ret = getResponse(response.getEntity(), encode);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw e;
		} finally {
			if (response != null) {
				EntityUtils.consume(response.getEntity()); // 会自动释放连接
			}
		}
		return ret;
	}

	private static final String APPLICATION_JSON = "application/json;charset=UTF-8";
    
	public static String post(HttpClient httpClient, String url, String content, Map<String, String> headers,
							  String encode) throws Exception {
		String ret = "";
		HttpResponse response = null;
		try {
			HttpPost httppost = new HttpPost(url);
			httppost.addHeader("User-Agent", USER_AGENT);
			if (headers != null && !headers.isEmpty()) {
                headers.forEach((key, value) -> {
                    if (StringUtils.isNotBlank(key)) {
                        httppost.addHeader(key, value);
                    }
                });
            }

			if (content == null) {
				List<NameValuePair> nvps = new ArrayList<NameValuePair>();
				httppost.setEntity(new UrlEncodedFormEntity(nvps, encode));
			} else {
				 StringEntity myEntity = new StringEntity(content, encode);
				 myEntity.setContentType(APPLICATION_JSON);
				 //myEntity.setContentEncoding(new BasicHeader(HTTP.CONTENT_ENCODING, "default"));
				 //myEntity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, APPLICATION_JSON));
				 httppost.setEntity(myEntity);
			}
			response = httpClient.execute(httppost);
			ret = getResponse(response.getEntity(), encode);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			if (response != null) {
				EntityUtils.consume(response.getEntity()); // 会自动释放连接
			}
		}
		return ret;
	}

	public static String post(HttpClient httpClient, String url, Map<String, String> params, String encode) throws Exception {
		String ret = "";
		HttpResponse response = null;
		try {
			HttpPost httppost = new HttpPost(url);
			httppost.addHeader("User-Agent", USER_AGENT);
			httppost.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
			List<NameValuePair> nvps = new ArrayList<NameValuePair>();

			Set<String> keySet = params.keySet();
			for (String key : keySet) {
				nvps.add(new BasicNameValuePair(key, params.get(key)));
			}
			httppost.setEntity(new UrlEncodedFormEntity(nvps, encode));

			response = httpClient.execute(httppost);
			ret = getResponse(response.getEntity(), encode);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			if (response != null) {
				EntityUtils.consume(response.getEntity()); // 会自动释放连接
			}
		}
		return ret;
	}

	/**
	 * post 请求 ，根据参数设置post 方式
	 *
	 * @param httpClient
	 * @param url
	 * @param content
	 * @param params
	 * @return
	 * @throws Exception
	 */
	public static String post(HttpClient httpClient, String url, String content, Map<String, String> params) throws Exception {
		String ret = "";
		String encode = "utf-8";
		HttpResponse response = null;

		boolean noContent = false;
		if (content == null || content.isEmpty()) {
			noContent = true;
		}

		if (!noContent) {

			Set<String> keySet = params.keySet();
			String paramsText = "";
			for (String key : keySet) {
				paramsText += (key + "=" + params.get(key) + "&");
			}


			if (!paramsText.isEmpty()) {
				url += ("?" + paramsText.substring(0,paramsText.length()-1));
			}
		}

		try {

			HttpPost httppost = new HttpPost(url);
			httppost.addHeader("User-Agent", USER_AGENT);

			if (noContent) {
				httppost.addHeader("Content-Type", "application/x-www-form-urlencoded");
				List<NameValuePair> nvps = new ArrayList<NameValuePair>();

				Set<String> keySet = params.keySet();
				for (String key : keySet) {
					nvps.add(new BasicNameValuePair(key, params.get(key)));
				}
				httppost.setEntity(new UrlEncodedFormEntity(nvps, encode));
			}else {
				StringEntity myEntity = new StringEntity(content, encode);
				myEntity.setContentType(APPLICATION_JSON);
				myEntity.setContentEncoding(new BasicHeader(HTTP.CONTENT_ENCODING, "utf-8"));
				httppost.setEntity(myEntity);
			}
			response = httpClient.execute(httppost);
			ret = getResponse(response.getEntity(), encode);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			if (response != null) {
				EntityUtils.consume(response.getEntity()); // 会自动释放连接
			}
		}
		return ret;
	}

	/**
	 * post请求--post文件
	 * 
	 * @param httpClient
	 * @param url
	 * @param content
	 * @param encode
	 * @return
	 * @throws Exception
	 */
	public static String post(HttpClient httpClient, String url, File content, String encode) throws Exception {
		String ret = "";
		HttpResponse response = null;
		try {
			HttpPost httppost = new HttpPost(url);
			httppost.addHeader("User-Agent", USER_AGENT);
			if (content == null) {
				List<NameValuePair> nvps = new ArrayList<NameValuePair>();
				httppost.setEntity(new UrlEncodedFormEntity(nvps, encode));
			} else {
				FileEntity myEntity = new FileEntity(content);
				httppost.setEntity(myEntity);
			}

			response = httpClient.execute(httppost);
			ret = getResponse(response.getEntity(), encode);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			if (response != null) {
				EntityUtils.consume(response.getEntity()); // 会自动释放连接
			}
		}
		return ret;
	}
	
	public static void main(String[] args) {
		double d = 23.456;
		int i = (int)d;
		System.out.print(i);
		
//		for (int i = 0; i < 10; i++) {
//			try {
//				HttpUtil.httpGet("http://blog.sina.com.cn/s/blog_74d0f5e501010pzz.html");
//			} catch (Exception e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
//		}
//
//		try {
//			System.in.read();
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
	}

}
